#include "oled_sprintf.h"

// 缓冲区定义
char lcd_line_buffer[MAX_LINE][MAX_COL];       // 当前帧要显示的内容
char lcd_line_shadow[MAX_LINE][MAX_COL];       // 上一帧内容，用于比较差异

uint8_t menu_mode = 0;
uint8_t cursor_0 = 0;
uint8_t cursor_1 = 0;

//==================== 实际 SPI 写屏函数 ====================//
void oled_sprintf(uint16_t line, uint16_t col, const char *format, ...)
{
    #define BUFFER_SIZE 256
    char str[BUFFER_SIZE];

    va_list args;
    va_start(args, format);
    int len = vsnprintf(str, BUFFER_SIZE, format, args);
    va_end(args);

    if (len > 0)
    {
        uint16_t fc = WHITE;
        uint16_t bc = BLACK;
        uint8_t sizey = FONT_H;
        uint8_t mode = 0;

        uint16_t x_pix = col * FONT_W;
        uint16_t y_pix = line * FONT_H;

        LCD_ShowString(x_pix, y_pix, (const uint8_t *)str, fc, bc, sizey, mode);
    }
}

//==================== 缓存更新函数 ====================//
void oled_sprintf_buffer(uint16_t line, uint16_t col, const char *format, ...)
{
    if (line >= MAX_LINE || col >= MAX_COL) return;

    char *dst = lcd_line_buffer[line] + col;
    size_t maxlen = MAX_COL - col;

    va_list args;
    va_start(args, format);
    vsnprintf(dst, maxlen, format, args);
    va_end(args);
}

//==================== 缓存→屏幕 刷新一行 ====================//
void lcd_refresh_task(void)
{
    static uint8_t line = 0;

    if (strcmp(lcd_line_buffer[line], lcd_line_shadow[line]) != 0)
    {
        oled_sprintf(line, 0, "%s", lcd_line_buffer[line]);
        strcpy(lcd_line_shadow[line], lcd_line_buffer[line]);
    }

    line++;
    if (line >= MAX_LINE)
        line = 0;
}

//==================== 屏幕数据更新函数（只更新 buffer） ====================//
void lcd_proc(void)
{
    // 可选：每帧清空 buffer
    for (int i = 0; i < MAX_LINE; i++)
        memset(lcd_line_buffer[i], ' ', MAX_COL - 1), lcd_line_buffer[i][MAX_COL - 1] = '\0';

    if (menu_mode == 0)
    {
        oled_sprintf_buffer(0, 2, "page: %d         ", menu_mode);
        oled_sprintf_buffer(1, 2, "Yaw: %.2f        "/* , Yaw */);       
        oled_sprintf_buffer(5, 2, "Hello World!     ");
        oled_sprintf_buffer(6, 2, "%d %d %d %d %d %d %d %d", 
            Normal[0], Normal[1], Normal[2], Normal[3], Normal[4], Normal[5], Normal[6], Normal[7]);
        oled_sprintf_buffer(7, 12, "NOW time: %d", get_tick());
        //oled_sprintf_buffer(cursor_0, CURSOR_COL, "*");
    }
    else if (menu_mode == 1)
    {
        oled_sprintf(0, 2, "page: %d         ", menu_mode);
        oled_sprintf(1, 2, "Yaw_kp: %.2f     ", PID_data_array[0][0]);  
        oled_sprintf(2, 2, "Yaw_ki: %.2f     ", PID_data_array[0][1]);  
        oled_sprintf(3, 2, "Yaw_kd: %.2f     ", PID_data_array[0][2]);  
        oled_sprintf(4, 2, "GW_Kp: %.2f      ", PID_data_array[1][0]);  
        oled_sprintf(5, 2, "GW_ki: %.2f      ", PID_data_array[1][1]);  
        oled_sprintf(6, 2, "GW_Kd: %.2f      ", PID_data_array[1][2]);  
        oled_sprintf(cursor_1, CURSOR_COL, "*");
        oled_sprintf(cursor_1-1, CURSOR_COL, " ");
        oled_sprintf(7, CURSOR_COL, " ");
    }
    else 
    {
        oled_sprintf_buffer(0, 2, "page: %d", menu_mode);
        oled_sprintf_buffer(1, 2, "undefined page   ");
        for (int i = 2; i < 9; i++)
            oled_sprintf_buffer(i, 2, "undefined data   ");
    }
}